home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb-4.5 / dist / gdb / rem-multi.shar / remote_gutils.c next >
Encoding:
C/C++ Source or Header  |  1991-11-12  |  8.9 KB  |  408 lines

  1. /* General utility routines for the remote server for GDB, the GNU debugger.
  2.    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdio.h>
  21. #include <sys/ioctl.h>
  22. #include "defs.h"
  23.  
  24. void error ();
  25. void fatal ();
  26.  
  27. /* Chain of cleanup actions established with make_cleanup,
  28.    to be executed if an error happens.  */
  29.  
  30. static struct cleanup *cleanup_chain;
  31.  
  32. /* Nonzero means a quit has been requested.  */
  33.  
  34. int quit_flag;
  35.  
  36. /* Nonzero means quit immediately if Control-C is typed now,
  37.    rather than waiting until QUIT is executed.  */
  38.  
  39. int immediate_quit;
  40.  
  41. /* Add a new cleanup to the cleanup_chain,
  42.    and return the previous chain pointer
  43.    to be passed later to do_cleanups or discard_cleanups.
  44.    Args are FUNCTION to clean up with, and ARG to pass to it.  */
  45.  
  46. struct cleanup *
  47. make_cleanup (function, arg)
  48.      void (*function) ();
  49.      int arg;
  50. {
  51.   register struct cleanup *new
  52.     = (struct cleanup *) xmalloc (sizeof (struct cleanup));
  53.   register struct cleanup *old_chain = cleanup_chain;
  54.  
  55.   new->next = cleanup_chain;
  56.   new->function = function;
  57.   new->arg = arg;
  58.   cleanup_chain = new;
  59.  
  60.   return old_chain;
  61. }
  62.  
  63. /* Discard cleanups and do the actions they describe
  64.    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
  65.  
  66. void
  67. do_cleanups (old_chain)
  68.      register struct cleanup *old_chain;
  69. {
  70.   register struct cleanup *ptr;
  71.   while ((ptr = cleanup_chain) != old_chain)
  72.     {
  73.       (*ptr->function) (ptr->arg);
  74.       cleanup_chain = ptr->next;
  75.       free (ptr);
  76.     }
  77. }
  78.  
  79. /* Discard cleanups, not doing the actions they describe,
  80.    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
  81.  
  82. void
  83. discard_cleanups (old_chain)
  84.      register struct cleanup *old_chain;
  85. {
  86.   register struct cleanup *ptr;
  87.   while ((ptr = cleanup_chain) != old_chain)
  88.     {
  89.       cleanup_chain = ptr->next;
  90.       free (ptr);
  91.     }
  92. }
  93.  
  94. /* This function is useful for cleanups.
  95.    Do
  96.  
  97.      foo = xmalloc (...);
  98.      old_chain = make_cleanup (free_current_contents, &foo);
  99.  
  100.    to arrange to free the object thus allocated.  */
  101.  
  102. void
  103. free_current_contents (location)
  104.      char **location;
  105. {
  106.   free (*location);
  107. }
  108.  
  109. /* Generally useful subroutines used throughout the program.  */
  110.  
  111. /* Like malloc but get error if no storage available.  */
  112.  
  113. char *
  114. xmalloc (size)
  115.      long size;
  116. {
  117.   register char *val = (char *) malloc (size);
  118.   if (!val)
  119.     fatal ("virtual memory exhausted.", 0);
  120.   return val;
  121. }
  122.  
  123. /* Like realloc but get error if no storage available.  */
  124.  
  125. char *
  126. xrealloc (ptr, size)
  127.      char *ptr;
  128.      long size;
  129. {
  130.   register char *val = (char *) realloc (ptr, size);
  131.   if (!val)
  132.     fatal ("virtual memory exhausted.", 0);
  133.   return val;
  134. }
  135.  
  136. /* Print the system error message for errno, and also mention STRING
  137.    as the file name for which the error was encountered.
  138.    Then return to command level.  */
  139.  
  140. void
  141. perror_with_name (string)
  142.      char *string;
  143. {
  144.   extern int sys_nerr;
  145.   extern char *sys_errlist[];
  146.   extern int errno;
  147.   char *err;
  148.   char *combined;
  149.  
  150.   if (errno < sys_nerr)
  151.     err = sys_errlist[errno];
  152.   else
  153.     err = "unknown error";
  154.  
  155.   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  156.   strcpy (combined, string);
  157.   strcat (combined, ": ");
  158.   strcat (combined, err);
  159.  
  160.   error ("%s.", combined);
  161. }
  162.  
  163. /* Print the system error message for ERRCODE, and also mention STRING
  164.    as the file name for which the error was encountered.  */
  165.  
  166. void
  167. print_sys_errmsg (string, errcode)
  168.      char *string;
  169.      int errcode;
  170. {
  171.   extern int sys_nerr;
  172.   extern char *sys_errlist[];
  173.   char *err;
  174.   char *combined;
  175.  
  176.   if (errcode < sys_nerr)
  177.     err = sys_errlist[errcode];
  178.   else
  179.     err = "unknown error";
  180.  
  181.   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  182.   strcpy (combined, string);
  183.   strcat (combined, ": ");
  184.   strcat (combined, err);
  185.  
  186.   printf ("%s.\n", combined);
  187. }
  188.  
  189. void
  190. quit ()
  191. {
  192.   fflush (stdout);
  193.   ioctl (fileno (stdout), TIOCFLUSH, 0);
  194.   error ("Quit");
  195. }
  196.  
  197. /* Control C comes here */
  198.  
  199. void
  200. request_quit ()
  201. {
  202.   quit_flag = 1;
  203.   if (immediate_quit)
  204.     quit ();
  205. }
  206.  
  207. /* Print an error message and return to command level.
  208.    STRING is the error message, used as a fprintf string,
  209.    and ARG is passed as an argument to it.  */
  210.  
  211. void
  212. error (string, arg1, arg2, arg3)
  213.      char *string;
  214.      int arg1, arg2, arg3;
  215. {
  216.   fflush (stdout);
  217.   fprintf (stderr, string, arg1, arg2, arg3);
  218.   fprintf (stderr, "\n");
  219.   /************return_to_top_level ();************/ 
  220. }
  221.  
  222. /* Print an error message and exit reporting failure.
  223.    This is for a error that we cannot continue from.
  224.    STRING and ARG are passed to fprintf.  */
  225.  
  226. void
  227. fatal (string, arg)
  228.      char *string;
  229.      int arg;
  230. {
  231.   fprintf (stderr, "gdb: ");
  232.   fprintf (stderr, string, arg);
  233.   fprintf (stderr, "\n");
  234.   exit (1);
  235. }
  236.  
  237. /* Make a copy of the string at PTR with SIZE characters
  238.    (and add a null character at the end in the copy).
  239.    Uses malloc to get the space.  Returns the address of the copy.  */
  240.  
  241. char *
  242. savestring (ptr, size)
  243.      char *ptr;
  244.      int size;
  245. {
  246.   register char *p = (char *) xmalloc (size + 1);
  247.   bcopy (ptr, p, size);
  248.   p[size] = 0;
  249.   return p;
  250. }
  251.  
  252. void
  253. print_spaces (n, file)
  254.      register int n;
  255.      register FILE *file;
  256. {
  257.   while (n-- > 0)
  258.     fputc (' ', file);
  259. }
  260.  
  261. /* Ask user a y-or-n question and return 1 iff answer is yes.
  262.    Takes three args which are given to printf to print the question.
  263.    The first, a control string, should end in "? ".
  264.    It should not say how to answer, because we do that.  */
  265.  
  266. int
  267. query (ctlstr, arg1, arg2)
  268.      char *ctlstr;
  269. {
  270.   register int answer;
  271.  
  272.   /* Automatically answer "yes" if input is not from a terminal.  */
  273.   /***********if (!input_from_terminal_p ())
  274.     return 1; *************************/ 
  275.  
  276.   while (1)
  277.     {
  278.       printf (ctlstr, arg1, arg2);
  279.       printf ("(y or n) ");
  280.       fflush (stdout);
  281.       answer = fgetc (stdin);
  282.       clearerr (stdin);        /* in case of C-d */
  283.       if (answer != '\n')
  284.     while (fgetc (stdin) != '\n') clearerr (stdin);
  285.       if (answer >= 'a')
  286.     answer -= 040;
  287.       if (answer == 'Y')
  288.     return 1;
  289.       if (answer == 'N')
  290.     return 0;
  291.       printf ("Please answer y or n.\n");
  292.     }
  293. }
  294.  
  295. /* Parse a C escape sequence.  STRING_PTR points to a variable
  296.    containing a pointer to the string to parse.  That pointer
  297.    is updated past the characters we use.  The value of the
  298.    escape sequence is returned.
  299.  
  300.    A negative value means the sequence \ newline was seen,
  301.    which is supposed to be equivalent to nothing at all.
  302.  
  303.    If \ is followed by a null character, we return a negative
  304.    value and leave the string pointer pointing at the null character.
  305.  
  306.    If \ is followed by 000, we return 0 and leave the string pointer
  307.    after the zeros.  A value of 0 does not mean end of string.  */
  308.  
  309. int
  310. parse_escape (string_ptr)
  311.      char **string_ptr;
  312. {
  313.   register int c = *(*string_ptr)++;
  314.   switch (c)
  315.     {
  316.     case 'a':
  317.       return '\a';
  318.     case 'b':
  319.       return '\b';
  320.     case 'e':
  321.       return 033;
  322.     case 'f':
  323.       return '\f';
  324.     case 'n':
  325.       return '\n';
  326.     case 'r':
  327.       return '\r';
  328.     case 't':
  329.       return '\t';
  330.     case 'v':
  331.       return '\v';
  332.     case '\n':
  333.       return -2;
  334.     case 0:
  335.       (*string_ptr)--;
  336.       return 0;
  337.     case '^':
  338.       c = *(*string_ptr)++;
  339.       if (c == '\\')
  340.     c = parse_escape (string_ptr);
  341.       if (c == '?')
  342.     return 0177;
  343.       return (c & 0200) | (c & 037);
  344.       
  345.     case '0':
  346.     case '1':
  347.     case '2':
  348.     case '3':
  349.     case '4':
  350.     case '5':
  351.     case '6':
  352.     case '7':
  353.       {
  354.     register int i = c - '0';
  355.     register int count = 0;
  356.     while (++count < 3)
  357.       {
  358.         if ((c = *(*string_ptr)++) >= '0' && c <= '7')
  359.           {
  360.         i *= 8;
  361.         i += c - '0';
  362.           }
  363.         else
  364.           {
  365.         (*string_ptr)--;
  366.         break;
  367.           }
  368.       }
  369.     return i;
  370.       }
  371.     default:
  372.       return c;
  373.     }
  374. }
  375.  
  376. void
  377. printchar (ch, stream)
  378.      unsigned char ch;
  379.      FILE *stream;
  380. {
  381.   register int c = ch;
  382.   if (c < 040 || c >= 0177)
  383.     {
  384.       if (c == '\n')
  385.     fprintf (stream, "\\n");
  386.       else if (c == '\b')
  387.     fprintf (stream, "\\b");
  388.       else if (c == '\t')
  389.     fprintf (stream, "\\t");
  390.       else if (c == '\f')
  391.     fprintf (stream, "\\f");
  392.       else if (c == '\r')
  393.     fprintf (stream, "\\r");
  394.       else if (c == 033)
  395.     fprintf (stream, "\\e");
  396.       else if (c == '\a')
  397.     fprintf (stream, "\\a");
  398.       else
  399.     fprintf (stream, "\\%03o", c);
  400.     }
  401.   else
  402.     {
  403.       if (c == '\\' || c == '"' || c == '\'')
  404.     fputc ('\\', stream);
  405.       fputc (c, stream);
  406.     }
  407. }
  408.